package com.cskaoyan.util;

import com.cskaoyan.mapper.LogMapper;
import com.cskaoyan.model.Admin;
import com.cskaoyan.model.Log;
import com.cskaoyan.model.vo.BaseRespVO;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

/**
 * @author ：SZ HIT LYC
 * @description: 使用AOP记录安全操作和订单操作
 * @date ：2022/5/9 16:54
 */

@Component
@Aspect
public class LoggingAspect {

    @Autowired
    LogMapper logMapper;

    @Autowired
    HttpServletRequest request;

    //登录操作切入点
    @Pointcut("execution(* com.cskaoyan.controller.backStage.AuthController.login(..))")
    public void systemOperationPointcut() {
    }

    // 系统操作切入点
    @Pointcut("execution(* com.cskaoyan.controller..AdminController.*(com.cskaoyan.model.Admin, *))")
    public void adminOperationPointcut() {
    }

    // 订单操作切入点
    @Pointcut("execution(* com.cskaoyan.controller..OrderController.*(java.util.Map))")
    public void orderOperationPointcut() {
    }

    @Around("systemOperationPointcut()")
    public Object operationAdminLoginLogging(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        Object proceed = proceedingJoinPoint.proceed();
        Object[] args = proceedingJoinPoint.getArgs();
        Map map = (Map) args[0];
        String username = (String) map.get("username");
        String remoteAddr = request.getRemoteAddr();
        Date now = new Date(System.currentTimeMillis());
        Log log = new Log();
        Subject subject = SecurityUtils.getSubject();
        // String username = (String) subject.getPrincipals().getPrimaryPrincipal();
        // if (username != null) {
        log.setAdmin(username);
        // }
        log.setIp(remoteAddr);
        log.setType(1);
        log.setAction("登录");

        if (subject.isAuthenticated()) {
            log.setStatus(true);
            log.setResult("成功登录");
        } else {
            log.setStatus(false);
            log.setResult("账号或密码错误");
        }
        log.setAddTime(now);
        log.setUpdateTime(now);
        log.setDeleted(false);
        logMapper.insertSelective(log);

        return proceed;
    }

    @Around("adminOperationPointcut()")
    public Object operationAdminModifyLogging(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object proceed = proceedingJoinPoint.proceed();
        boolean notLogin = false;
        Subject subject = SecurityUtils.getSubject();
        if (subject.getPrincipals() == null) {
            notLogin = true;
        }

        BaseRespVO res = (BaseRespVO) proceed;

        String remoteAddr = request.getRemoteAddr();
        Date now = new Date(System.currentTimeMillis());
        Log log = new Log();
        log.setIp(remoteAddr);
        log.setType(1);
        String signature = proceedingJoinPoint.getSignature().getName().toLowerCase();
        if (signature.contains("create")) {
            log.setAction("创建管理员");
        } else if (signature.contains("update")) {
            log.setAction("更新管理员");
        } else if (signature.contains("delete")) {
            log.setAction("删除管理员");
        }
        if (res.getErrno() == 0 && !notLogin) {
            log.setStatus(true);
            log.setResult("操作成功");
        } else {
            log.setStatus(false);
            log.setResult("操作失败");
        }

        log.setAddTime(now);
        log.setUpdateTime(now);
        log.setDeleted(false);


        PrincipalCollection principals = subject.getPrincipals();
        if (principals != null) {
            String username = (String) principals.getPrimaryPrincipal();
            log.setAdmin(username);
        }
        logMapper.insertSelective(log);
        return proceed;
    }

    @Around("orderOperationPointcut()")
    public Object operationOrderModifyLogging(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object proceed = proceedingJoinPoint.proceed();
        boolean notLogin = false;
        Subject subject = SecurityUtils.getSubject();
        if (subject.getPrincipals() == null) {
            notLogin = true;
        }

        BaseRespVO res = (BaseRespVO) proceed;

        String remoteAddr = request.getRemoteAddr();
        Date now = new Date(System.currentTimeMillis());
        Log log = new Log();
        log.setIp(remoteAddr);
        log.setType(2);
        String signature = proceedingJoinPoint.getSignature().getName().toLowerCase();
        if (signature.contains("ship")) {
            log.setAction("发货操作");
        } else if (signature.contains("delete")) {
            log.setAction("删除订单");
        } else if (signature.contains("refund")) {
            log.setAction("退款");
        }

        if (res.getErrno() == 0 && !notLogin) {
            log.setStatus(true);
            log.setResult("操作成功");
        } else {
            log.setStatus(false);
            log.setResult("操作失败");
        }


        log.setAddTime(now);
        log.setUpdateTime(now);
        log.setDeleted(false);

        PrincipalCollection principals = subject.getPrincipals();
        if (principals != null) {
            String username = (String) principals.getPrimaryPrincipal();
            log.setAdmin(username);
        }
        logMapper.insertSelective(log);
        return proceed;
    }

}
